﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
////using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using System.Diagnostics;
using log4net;
using RollBack.src.ui.ExplorerView;
using RollBack.src.ui;

namespace RollBack.src.ui
{
    /// <summary>
    /// UI split panel with left side containing drives and directories and right side containing the files and directories.
    /// </summary>
    public partial class Explorer2PaneView : UserControl
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(Explorer2PaneView));
        private ExplorerView.ExplorerData m_explorerData;

        public Explorer2PaneView()
        {
            InitializeComponent();
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.DoubleBuffer, true);

            // Allows for catching the WM_ERASEBKGND message
            SetStyle(ControlStyles.EnableNotifyMessage, true);
        }

        public void setExplorerData(ExplorerData data)
        {
            if (data != null)
            {
                // set the explorer data for the left and right panel
                m_explorerData = data;
                m_rightPanel.setExplorerData(m_explorerData);
                m_leftPanel.m_explorerViewData = m_explorerData;
                TreeNode node = m_leftPanel.RefreshRootNode(2);
                if(node != null) {
                    refreshRightPanel(node, false);
                }
            }
        }

        void leftPanelKeyHandler(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            if (e.KeyCode == System.Windows.Forms.Keys.F5 ||
                e.KeyCode == System.Windows.Forms.Keys.Right ||
                e.KeyCode == System.Windows.Forms.Keys.Down ||
                e.KeyCode == System.Windows.Forms.Keys.Up)
            {
                TreeNode node = m_leftPanel.getSelectedNode();
                if (node != null)
                {
                    refreshNode(node,true);
                }
            }
        }

        /// <summary>
        /// refresh the node
        /// </summary>
        /// <param name="curr"></param>
        private void refreshNode(TreeNode curr,bool force)
        {
            using (BusyCursor bc = new BusyCursor(this))
            {
                m_rightPanel.ClearItems();
                string fullPath = curr.FullPath;
                try
                {
                    // populate the directories on the left side.
                    if ((curr.Nodes.Count == 0) || force)
                    {
                        m_leftPanel.expandNode(curr,force);
                        refreshRightPanel(curr,force);
                    }
                }
                catch (IOException e)
                {
                    log.Warn("Error populating " + fullPath, e);
                }
                catch (Exception e)
                {
                    log.Warn("Error refreshing directory.", e);
                    AppUI.ShowException("Error reading dir <" + fullPath + ">", e);
                }
            }
        }

        /// <summary>
        /// Refresh the right panel based on the node selected on the left panel
        /// </summary>
        /// <param name="curr"></param>
        private void refreshRightPanel(TreeNode curr,bool force)
        {
            if (curr != null && (m_explorerData.RootDisplayNodePath != null) && !curr.Text.Equals(m_explorerData.RootDisplayNode))
            {
                // populate files on the right side of the window
                bool checkAll = curr.StateImageIndex == ThreeStateTreeView.STATE_CHECKED;
                string dir = curr.FullPath;
                if (dir.Length > m_explorerData.RootDisplayNodePath.Length)
                {
                    dir = dir.Substring(m_explorerData.RootDisplayNodePath.Length);
                }
                m_rightPanel.expandNode(dir, checkAll,force);
            }
        }

        private void treeNodeClickEventHandler(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node != null)
            {
                try
                {
                    bool force = false;
                    m_leftPanel.expandNode(e.Node,force);
                    m_leftPanel.onMouseClick(sender, e);
                    TreeNode tn = m_leftPanel.getSelectedNode();
                    refreshRightPanel(tn, force);
                }
                catch (IOException ex)
                {
                    AppUI.ShowMessage(ex.Message);
                }
            }
        }

        /// <summary>
        /// Refresh the root node and expand as many levels as specified by 'level'
        /// </summary>
        /// <param name="level"></param>
        internal void RefreshRootNode(int level)
        {
            TreeNode node = m_leftPanel.RefreshRootNode(level);
            if (node != null)
            {
                refreshRightPanel(node, false);
            }
        }
    }
}
